<?php
/**
 * @name Auth: Authorisation and Permission managment library extension
 * @version 1.8.0, September 26, 2007
 * @copyright &copy; 2006 Novachok, A.
 * @author iSnow (Novachok Alexandr) <novachok@ukr.net>
 * @package Functions Library
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
$_FUNC['serial']  = 20070926;
$_FUNC['version'] = "1.8.0";


/**
 * Function to Get IP address of visitor
 *
 * @return string
 */
function get_ip()
{
   if(getenv('HTTP_X_FORWARDED_FOR'))
   {
      $ip=getenv('HTTP_X_FORWARDED_FOR');
   } else {
      $ip=getenv('REMOTE_ADDR');
   }

   return $ip;
}

/**
 * Function for Roundign size of files.
 *
 * @param integer $size
 * @return string $size
 */
function RoundSizeBites(&$size)
{
   if($size == '')
   {
      $size = false;
   } else
   {
      if ($size >= 1048576) {
         $size = round($size / 1048576 * 100) / 100 . " Mb";
      } elseif ($size >= 1024) {
         $size = round($size / 1024 * 100) / 100 . " Kb";
      } else {
         $size = $size . " b";
      }
   }
}

/**
 * Secure prepare of a string
 *
 * @param sting $str
 * @return string $str
 */
function prepare_str ($str, $length = 0)
{
   isDigit($length);
   if($str == '') return false;

   $str = strip_tags($str);
   $str = htmlspecialchars($str);
   $str = stripslashes($str);
   $str = trim($str);

   if($length != false) $str = substr($str, 0, $length);
   settype($str, 'string');

   return $str;
}

/**
* Function for Check string for English chars with or not spaces
* @param string $str
* @param bool $noChar
* @return string|false
*/
function isAlpha(&$str, $Gaps = false)
{
   if($str == '')
   {
      $str = false;
   } else
   {
      if($Gaps === false)
      {
         $patern = "/^[_a-zA-Z0-9-]+$/";
      } else
      {
         $patern = "/^[_a-zA-Z0-9- ]+$/";
      }

      if(!preg_match($patern, $str))
      {
         $str = false;
      }
   }

   return $str;
}

/**
 * Function for check and preparation of float integer.
 * @param string|integer $decimal
 * @return float|false Integer which represent fiscal string $decimal
 */
function isMoneySum(&$decimal)
{
   isFloat($decimal);
}
function isFloat(&$float)
{
   if($float === '' || $float === false)
   {
      $float = false;
   } else
   {
      $float = str_replace(",", ".", $float);
      if(!ereg("^[0-9.]", $float))
      {
         $float = false;
      }
   }
   settype($float, 'float');
   return $float;
}

/**
 * Check is string digit or not
 *
 * @param string $str
 * @return string|false $str
 */
function isDigit(&$str, $params = null)
{
   if($params == 'NOZERRO' && $str == 0)
   {
      $str = false;
   } elseif($str === '' || $str === false)
   {
      $str = false;
   } else
   {
      if(preg_match("/^[0-9]+$/", trim($str)))
      {
         settype($str, 'integer');
      } else
      {
         $str = false;
      }
   }

   return $str;
}

/**
 * Check is string valid URL
 *
 * @param string $str
 */
function isUrl(&$str)
{
   if($str == '')
   {
      $str = false;
   } else
   {
      if(!preg_match('/^(http|ftp|https):\/\/([.\/_a-z0-9-])+$/i', $str))
      {
         $str = 'http://'.$str;
         if(!preg_match('/^(http|ftp|https):\/\/([.\/_a-z0-9-])+$/i', $str))
         {
            $str = false;
         }
      }
   }

   return $str;
}

function isIP(&$str)
{
   if($str == '')
   {
      $str = false;
   } else
   {
      if(!preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}+$/", $str))
      {
         $str = false;
      }
   }
}

function isBool(&$str)
{
   if($str == 1 || $str === 'yes' || $str === 'YES' || $str === true || $str === "true")
   {
      $str = true;
   } else
   {
      $str = false;
   }
   return $str;
}

/**
 * Validate e-mails
 *
 * @param string $email
 * @return string $email
 */
function isEmail(&$email)
{
   if($email == '')
   {
      $email = false;
   } else
   {
      $email = trim($email);
      $email = str_replace(' ', '', $email);
      if(!eregi("^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*$",$email))
      {
         $email = false;
      }
   }

   return $email;
}

/**
 * Reduction of a string a kind similarly to syntax of operator IN in MySQL
 *
 * @param string $str
 */
function makeIN(&$str)
{
   if($str == '') $str = false;
   $str = preg_replace("(\D+)", ',', $str);
}

/**
 * Generate Random string in length of $pass_len
 *
 * @param integer $pass_len
 * @return string $str
 */
function generate_pass($pass_len = 10)
{
   $allchars = 'abcdefghijklnmopqrstuvwxyzABCDEFGHIJKLNMOPQRSTUVWXYZ0123456789';
   $length = strlen($allchars);
   $str = '';
   mt_srand ((double) microtime() * 1000000);
   for ($i = 0; $i < $pass_len; $i++)
   {
      $str .= @$allchars{@mt_rand (0,$length)};
   }
   return $str;
}

/**
 * Convert win-1251 to utf-8
 *
 * @param string $str
 * @return string
 */
function cp1251_utf8($str)
{
   static $table = array(
      "\xA8" => "\xD0\x81",
      "\xB8" => "\xD1\x91",
      "\xA1" => "\xD0\x8E",
      "\xA2" => "\xD1\x9E",
      "\xAA" => "\xD0\x84",
      "\xAF" => "\xD0\x87",
      "\xB2" => "\xD0\x86",
      "\xB3" => "\xD1\x96",
      "\xBA" => "\xD1\x94",
      "\xBF" => "\xD1\x97",
      "\x8C" => "\xD3\x90",
      "\x8D" => "\xD3\x96",
      "\x8E" => "\xD2\xAA",
      "\x8F" => "\xD3\xB2",
      "\x9C" => "\xD3\x91",
      "\x9D" => "\xD3\x97",
      "\x9E" => "\xD2\xAB",
      "\x9F" => "\xD3\xB3",
   );
   
   return preg_replace('#[\x80-\xFF]#se',' "$0" >= "\xF0" ? "\xD1".chr(ord("$0")-0x70) : ("$0" >= "\xC0" ? "\xD0".chr(ord("$0")-0x30) : (isset($table["$0"]) ? $table["$0"] : ""))', $str);
}

/**
 * Convert  utf-8 to win-1251
 *
 * @param string $str
 * @return string
 */
function utf8_cp1251($str)
{
   static $table = array(
      "\xD0\x81" => "\xA8",
      "\xD1\x91" => "\xB8",
      "\xD0\x8E" => "\xA1",
      "\xD1\x9E" => "\xA2",
      "\xD0\x84" => "\xAA",
      "\xD0\x87" => "\xAF",
      "\xD0\x86" => "\xB2",
      "\xD1\x96" => "\xB3",
      "\xD1\x94" => "\xBA",
      "\xD1\x97" => "\xBF",
      "\xD3\x90" => "\x8C",
      "\xD3\x96" => "\x8D",
      "\xD2\xAA" => "\x8E",
      "\xD3\xB2" => "\x8F",
      "\xD3\x91" => "\x9C",
      "\xD3\x97" => "\x9D",
      "\xD2\xAB" => "\x9E",
      "\xD3\xB3" => "\x9F",
   );

   return preg_replace('#([\xD0-\xD1])([\x80-\xBF])#se', 'isset($table["$0"]) ? $table["$0"] : chr(ord("$2")+("$1" == "\xD0" ? 0x30 : 0x70))', $str);
}
                 

/**
 * Mail letter function
 *
 * @param string $name - Recipient's name
 * @param string $mail - Recipient's email
 * @param string $subject - Subject of message
 * @param string $message - Body of message
 * @param string $from_name - Sender's name
 * @param $from_mail - Sender's email
 * @return true|false on Succes sending
 */
function mailer($name, $mail, $subject, $message, $from_name, $from_mail, $codepage=''){
   $recipient = $name." <".$mail.">" . ", " ;
   $body = $message;
   $body .= date("Y-m-d H:i:s");
   $headers = '';

   if($codepage !== '')
   {
      $headers .= 'MIME-Version: 1.0'."\r\n";
      $headers .= 'Content-type: text/html; charset='.$codepage."\r\n";
   }

   $headers .= "From: ".$from_name." <".$from_mail.">\n";
   $headers .= "X-Sender: ".$from_mail."\n";
   $headers .= $from_name."\n";
   $headers .= "Return-Path: <".$from_mail.">\n";
   if(@mail($recipient, $subject, $body, $headers) == false)
   {
      return FALSE;
   } else
   {
      return TRUE;
   }
}

/**
 * Send e-mail usign Smarty Mail Template
 *
 * @uses Function Mailer();
 * @param string $tpl - fetched template
 * @param string $recipient - Recipient's name
 * @param string $to - Recipient's email
 * @param string $sender - Sender's name
 * @param string $from - Sender's email
 * @return true|false on Succes execute of mailer function
 */
function MakeMail_fromSmarty($tpl, $recipient, $to, $sender, $from, $codepage='')
{
   $lines = explode("\n", $tpl);
   $subject = trim(array_shift($lines));
   $body = join("\n", $lines);

   if(mailer($recipient, $to, $subject, $body, $sender, $from, $codepage))
   {
      return true;
   }
   return false;
}


/**
 * Get files list in Given directory
 *
 * @param string $dirName - Path of Given directory
 * @return array of Files names, directories and sym links in array:
 * returnet dates:  [dir]
 *                  [file]
 *                  [link]
 */
function getDirList ($dirName = '.')
{
   $content['file'] = false;
   $content['dir'] = false;
   $content['link'] = false;

   if(!substr($dirName, 0, 1) == '/')
   {
      $dirName = './'.$dirName;
   }
   $dirfd = opendir($dirName);
   if(!$dirfd) return false;

   while(($point = readdir($dirfd)) !== false)
   {
      if($point == '.' || $point == '..') continue;
      if(is_file($dirName.'/'.$point))
      {
         $content['file'][] = $point;
      }
      if(is_dir($dirName.'/'.$point))
      {
         $content['dir'][] = $point;

      }
      if(is_link($dirName.'/'.$point))
      {
         $content['link'][] = $point;
      }
   }
   closedir($dirfd);

   return $content;
}

/**
 * Make Name of uploaded file
 *
 * @param integer $int
 * @param string $ext - extention of file
 * @return string - file name
 */
function MakeFileName($int, $ext)
{
   if($int < 10)
   {
      $int = "000".$int;
   } elseif($int < 100)
   {
      $int = "00".$int;
   } elseif($int < 1000)
   {
      $int = "0".$int;
   }

   return $int.$ext;
}

/**
 * Make downloads of files
 * Can organize partially downloads
 *
 * @param string $file - file's path
 * @param sting $output_name - name for Agent
 * @param integer $allow_partilly
 * @return downloads
 */
function resume_download($file, $output_name, $allow_partilly)
{
   $ext = null;
   $range = 0;
   if(!is_file($file))
   {
      return false;
   }

   $filename = basename($file);
   $ext = strtolower(substr(strrchr($filename,"."),1));
   $filename = str_replace(' ', '_', $output_name);
   if($ext == null || $ext === false)
   {
      $ext = strtolower(substr(strrchr($output_name,"."),1));
   } else
   {
      $filename = $filename.'.'.$ext;
   }
   if(strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
   {
      $filename = preg_replace('/\./', '%de', $filename, substr_count($filename, '.') - 1);
   }
   $size = filesize($file);

   switch($ext)
   {
      case "exe": $mime = "application/octet-stream"; break;
      case "zip": $mime = "application/zip"; break;
      case "mp3": $mime = "audio/mpeg"; break;
      case "mpg": $mime = "video/mpeg"; break;
      case "avi": $mime = "video/x-msvideo"; break;
      case "mid":
      case "midi":
      case "kar": $mime = "audio/midi"; break;
      case "pdf": $mime = "application/pdf"; break;
      case "ogg": $mime = "application/ogg"; break;
      case "wav": $mime = "audio/x-wav"; break;
      case "jpg": $mime = "image/jpeg"; break;
      case "php":
      case "htm":
      case "html":
      case "txt": return false; break;

      default: $mime = "application/force-download";
   }

   if($allow_partilly == true)
   {
      header('Cache-Control: public');
      header('Content-Disposition: attachment; filename='.$filename);
      header('Content-Type: '.$mime);
      header("Content-Transfer-Encoding: binary");
      header('Accept-Ranges: bytes');
      if(isset($_SERVER['HTTP_RANGE']))
      {
         list($a, $range) = explode("=", $_SERVER['HTTP_RANGE']);
         str_replace($range, "-", $range);
         $new_length=$size-$range;
         header('HTTP/1.1 206 Partial Content');
         header('Content-Length: '.$new_length);
         header("Content-Range: bytes $range$size/$size");
      } else {
         header("Content-Range: bytes 0-$size/$size");
         header('Content-Length: '.$size);
      }

      $fp = fopen($file,"r");
      fseek($fp, $range);
      while(!feof($fp))
      {
         @set_time_limit(0);
         print(fread($fp,1024*8));
         flush();
      }
      fclose($fp);
   } else
   {
      header('Content-disposition: attachment; filename='.$filename);
      //header('Content-Type: application/force-download'); # didn't transfer MIME type, so i coment this, but, for now, should be more attend - may allow resume download
      header('Content-Type: '.$mime);
      header('Content-Transfer-Encoding: binary');
      header("Content-Length: ".$size);
      header("Pragma: no-cache");
      header("Expires: 0");

      readfile($file);
   }
}

/**
 * Upload Files to a Given Directory, Check if file exist and rename||replace downloaded
 *
 * @param string $filename - Original file name
 * @param string $destination - Destination of Downloads
 * @param string $tmp_name - Temporary downloaded filename
 * @param string $processing - What to do if File exist: RN - rename, RP - replace
 * @return filename || false
 */
function uploadfile($filename, $destination, $tmp_name, $processing = 'RN')
{
   if(is_uploaded_file($tmp_name))
   {
      $filename = basename($filename);

      if(substr($destination, 0, -1) == '/') $destination = substr($destination, 0 , strlen($destination) -1);

      if(substr($destination, 0, strlen($_SERVER['DOCUMENT_ROOT'])) != $_SERVER['DOCUMENT_ROOT'])
      {
         $destination = $_SERVER['DOCUMENT_ROOT'].$destination;
      } else
      {
         $destination = $destination;
      }

      $ext = (strpos($filename,'.')===false?'':'.'.substr(strrchr($filename, "."), 1));
      $base = substr($filename, 0, strlen($filename) - strlen($ext));
      $base = preg_replace("/\W/", "_", $base);
      $base = preg_replace("/[_]{2,}/", "_", $base);
      $fullpath = $destination.'/'.$base.$ext;
      $filename = $base.$ext;

      switch ($processing)
      {
         case 'RP': // Replace
         if(file_exists($fullpath))
         {
            @unlink($fullpath);
         }
         break;

         case 'RN': // Rename
         default:
         if(file_exists($fullpath))
         {
            for($i=1; file_exists($fullpath); $i++)
            {
               $filename = $base.'['.$i.']'.$ext;
               $fullpath = $destination.'/'.$filename;
            }
         }
      }

      if(@move_uploaded_file($tmp_name, $fullpath)) return $filename;

      return false;
   } else
   {
      return false;
   }
}

function ClearFileName(&$filename)
{
   $ext = (strpos($filename,'.')===false?'':'.'.substr(strrchr($filename, "."), 1));
   $base = substr($filename, 0, strlen($filename) - strlen($ext));
   $base = preg_replace("/\W/", "_", $base);
   $base = preg_replace("/[_]{2,}/", "_", $base);
   $filename = $base.$ext;
}

function MoveFile($from, $to, $mode = 'RN')
{
   if(!file_exists($from)) return false;

   $dirname  = dirname($to);
   switch ($mode)
   {
      case 'RP': // Replace
      if(file_exists($to))
      {
         @unlink($to);
      }
      break;

      case 'PN': // Just get Unique File Name 
         $filename = basename($to);
         
      case 'RN': // Rename
      default:
      if(file_exists($to))
      {
         $file = DevideFileName($to);
         for($i=1; file_exists($to); $i++)
         {
            $filename = $file['base'] . '[' . $i . ']' . $file['ext'];
            $to = $dirname.'/'.$filename;
         }
      }
   }

   if($mode != 'PN')
   {
      @copy($from, $to);
      @unlink($from);
   }
   return $filename;
}

function DevideFileName($filename)
{
   $filename = basename($filename);
   $file['ext']  = (strpos($filename, '.') === false ? '' : '.' . substr(strrchr($filename, '.'), 1));
   $file['base'] = substr($filename, 0, strlen($filename) - strlen($file['ext']));

   return $file;
}


/**
 * Deduct one array from other by values which present in both
 *
 * @param array $source - Source array
 * @param array $deduct - Slice array
 * @return array
 */
function deduct_array($source, $deduct)
{
   foreach($source as $key=>$value)
   {
      if(!in_array($value, $deduct))
      {
         $result[] = $value;
      }
   }
   return $result;
}


/**
 * Resize Image by Resample function
 *
 * @param string $source - source image file
 * @param string $destination - destination image file
 * @param array  $params - params for function
 *
 * Params can be:
 *        width      - integer,
 *        height     - integer,
 *        proportion - bool default: true
 *        fitsmaller - bool default: false
 */
function ImageResize($source, $destination, $params)
{
   if(!is_array($params)) return false;
   $proportion  = true;
   $result      = false;
   $fitsmaller  = false;
   $insize      = false;
   $dest_width  = 1;
   $dest_height = 1;

   $img_params = getimagesize($source);
   if($img_params == false)  return false;

   $source_width  = $img_params[0];
   $source_height = $img_params[1];
   $source_mime   = $img_params['mime'];
   unset($img_params);

   if(!in_array($source_mime, array('image/jpeg', 'image/png', 'image/gif'))) return false;

   // SET PARAMS
   foreach ($params as $key=>$value)
   {
      isAlpha($key);
      if($key != false)
      {
         switch ($key)
         {
            // Width of image
            case 'width':
            case 'WIDTH':
               isDigit($value);
               if($value != false) $dest_width = $value;
            break;

            // Height of image
            case 'height':
            case 'HEIGHT':
               isDigit($value);
               if($value != false) $dest_height = $value;
            break;

            // Saving of proportions at scaling
            case 'proportion':
            case 'PROPORTION':
               settype($value, 'bool');
               $proportion = $value;
            break;

            // Priority on a less side
            case 'fitsmaller':
            case 'FITSMALLER':
               settype($value, 'bool');
               $fitsmaller = $value;
            break;
            
            // 
            case 'insize':
            case 'INSIZE':
               settype($value, 'bool');
               $insize = $value;
         }
      }
   }

   // EXIT IF SOURCE IMAGE HAVE DESTINATION SIZES
   if($source_height == $dest_height && $source_width == $dest_width)
   {
      if($destination == $source)
      {
         unset($result);
         $result['width']    = $dest_width;
         $result['height']   = $dest_height;
         $result['filesize'] = filesize($destination);
         $result['mime']     = $source_mime;
         return $result;
      }

      if(@copy($source, $destination))
      {
         unset($result);
         $result['width']    = $dest_width;
         $result['height']   = $dest_height;
         $result['filesize'] = filesize($destination);
         $result['mime']     = $source_mime;

         return $result;
      }
      return false;
   }

   // EXIT IF SOURCE IMAGE LESS THEN DESTINATION IMAGE
   if($fitsmaller === false)
   {
      if($source_width <= $dest_width && $source_height <= $dest_height)
      {
         if($destination == $source)
         {
            unset($result);
            $result['width']    = $source_width;
            $result['height']   = $source_height;
            $result['filesize'] = filesize($destination);
            $result['mime']     = $source_mime;

            return $result;
         }

         if(@copy($source, $destination))
         {
            unset($result);
            $result['width']    = $source_width;
            $result['height']   = $source_height;
            $result['filesize'] = filesize($destination);
            $result['mime']     = $source_mime;

            return $result;
         }
         return false;
      }
   }

   // GET DEST SIZES IF PROPORTION IS TRUE
   if($proportion === true)
   {
      if(($source_height/$source_width) > ($dest_height/$dest_width))
      {
         $dest_width = round(($dest_height/$source_height)*$source_width); # Vertical processing
      } elseif (($source_height/$source_width) < ($dest_height/$dest_width))
      {
         $dest_height = round(($dest_width/$source_width)*$source_height); # Horizontal processing
      }
   }

   // READ SOURCE IMAGE
   switch ($source_mime)
   {
      case 'image/jpeg':
      $source_image = imagecreatefromjpeg($source);
      break;

      case 'image/png':
      $source_image = imagecreatefrompng($source);
      break;

      case 'image/gif':
      $source_image = imagecreatefromgif($source);
      break;
   }

   // RESIZE IMAGE
   $dest_image = imagecreatetruecolor($dest_width, $dest_height);
   if(!imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_width, $dest_height, $source_width, $source_height))
   {
      unset($dest_image, $source_image);
      return false;
   }

   unset($source_image);

   // WRITE IMAGE
   switch ($source_mime)
   {
      case 'image/jpeg':
      $result = imagejpeg($dest_image, $destination);
      break;

      case 'image/png':
      $result = @imagepng($dest_image, $destination);
      break;

      case 'image/gif':
      $result = @imagegif($dest_image, $destination);
      break;
   }

   unset($dest_image);
   if($result !== false)
   {
      unset($result);
      $result['width']    = $dest_width;
      $result['height']   = $dest_height;
      $result['filesize'] = filesize($destination);
      $result['mime']     = $source_mime;

      return $result;
   }

   return false;
}

/**
 * Replacement array_walk_recursive function from PHP5
 */
if(!function_exists('array_walk_recursive'))
{
   function array_walk_recursive(&$input, $funcname, $userdata='')
   {
      if(!is_callable($funcname)) return false;
      if(!is_array($input)) return false;

      foreach ($input as $key=>$value)
      {
         if(is_array($value))
         {
            array_walk_recursive(&$input[$key], $funcname, $userdata);
         } else
         {
            if($userdata != '')
            {
               $input[$key] = $funcname($value, $userdata);
            } else
            {
               $input[$key] = $funcname($value);
            }
         }
      }

      return true;
   }
}

/*
DEVELOPMENT HISTORY:
1.7.7 /20070418    + The second parameter ia added in function isDigit () with possible value NOZERRO
1.7.8 /20070418    + isFloat() function, isMoneySum() is interface for isFloat() for now.
1.7.9 /20070421    + add return $str to isBool() function
1.7.10/20070501    + add return $str to isAlpha() function
1.7.11/20070505    ^ repaired array_walk_recursive func on PHP4 versions.
1.7.14/20070714    ^ improve isUrl() function for allowing long url with pages links
1.7.15/20070818    ^ remove ctype_digit function from isDigit() because of its errors
1.8.0/20070818      + add function for charset convertion: cp1251->utf8 and utf8->cp1251
*/
?>